package com.dorukdestan.p2pshare.model;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetAddress;
import java.util.ArrayList;

import com.dorukdestan.p2pshare.logger.Logger;

public class DownloadingFile {

	private Logger logger;
	private File file;
	private RandomAccessFile randomAccessFile;
	private int indexCount;
	private int completedPercent;
	private String pathToSaveAfterFinish = Constants.SAVE_PATH;
	private String expectedHashValue;
	private long expectedLength;
	private ArrayList<InetAddress> peers;
	
	public DownloadingFile(String fileHash, long fileLength, String fileName, ArrayList<InetAddress> peers) {
		this.peers = peers;
		this.indexCount = 0;
		this.completedPercent = 0;
		this.expectedLength = fileLength;
		this.file = new File(pathToSaveAfterFinish + File.separator + fileName + Constants.getAndIncrementDownloadedFileCount());
		this.expectedHashValue = fileHash;
		this.indexCount = (int) (expectedLength / Constants.FILE_CHUNK_SIZE);
		this.logger = new Logger(getClass());
	}
	
	public synchronized void addChunk(int index, String data){
		try {
			getRandomAccessFile();
			randomAccessFile.seek(index * Constants.FILE_CHUNK_SIZE);
			randomAccessFile.write(data.getBytes());
			logger.debug("chunk added " + index);
		} catch (Exception e) {
			logger.error(e);
			return;
		} finally{
			try {
				randomAccessFile.close();
			} catch (IOException e) {
				logger.error(e);
			}
		}
		
		++indexCount;
		
		calculateCompletedPercent();
		
		checkIfDone();
	}

	private void calculateCompletedPercent() {
		logger.debug("expectedLength / Constants.FILE_CHUNK_SIZE: "+expectedLength / Constants.FILE_CHUNK_SIZE);
		completedPercent = (int) (100 * Math.abs((indexCount / (expectedLength / Constants.FILE_CHUNK_SIZE))));
		logger.debug(file.getName() + " completed " + completedPercent + "%");
	}

	private synchronized void getRandomAccessFile() throws FileNotFoundException {
		randomAccessFile = new RandomAccessFile(file, "rws");
	}

	private void checkIfDone() {
		if(file.length() >= expectedLength){
			completedPercent = 100;
			checkCrc();
		}
	}

	private void checkCrc() {
		SharedFile f = new SharedFile(file.getAbsolutePath());
		
		if(Long.parseLong(expectedHashValue ) != f.getHashValue()){
			logger.error("CRC check is failed for " + f.getName());
			logger.debug("expected crc: " + expectedHashValue);
			logger.debug("found crc: " + f.getHashValue());
			//TODO make a call back to GUI
		} 
		logger.info("CRC check succeeded for " + f.getName());
	}

	public File getFile() {
		return file;
	}

	public int getIndexCount() {
		return indexCount;
	}

	public String getPathToSaveAfterFinish() {
		return pathToSaveAfterFinish;
	}

	public void setPathToSaveAfterFinish(String pathToSaveAfterFinish) {
		this.pathToSaveAfterFinish = pathToSaveAfterFinish;
	}

	public int getCompletedPercent() {
		return completedPercent;
	}

	public ArrayList<InetAddress> getPeers() {
		return peers;
	}

	public String getExpectedHashValue() {
		return expectedHashValue;
	}

	public long getExpectedLength() {
		return expectedLength;
	}

}
